import ipynb.fs.full.features as features
from sklearn import preprocessing
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sb
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin_min
%matplotlib inline
from mpl_toolkits.mplot3d import Axes3D
plt.rcParams['figure.figsize'] = (16, 9)
plt.style.use('ggplot')
df_train = pd.read_csv('./data/train.csv')
df_aux_train = df_train
df_test = pd.read_csv('./data/test.csv')
df_aux_test = df_test
# Normalizacion
def _normalizacion(df, columnas):
x = df.values #returns a numpy array
min_max_scaler = preprocessing.MinMaxScaler()
x_scaled = min_max_scaler.fit_transform(x)
df = pd.DataFrame(x_scaled)
df.columns = columnas
return df
def generar_grafico(df_completo, columnas, df_y=[]):
""" df_completo: El df a calcular kmeans
columnas: Es con que columnas se va a calcular
df_y es la columna precio (es una serie)"""
"""Muestra el grafico de variacion entre 0 y 20 clusters(k)"""
"""Retorna X e y, para usar en el entrenamiento y la clasificacion"""
df = df_completo[columnas].copy()
for columna in columnas:
df[columna] = df[columna].fillna(df[columna].mean())
df = _normalizacion(df, columnas)
X = np.array(df[columnas])
y = None if type(df_y) == list else np.array(df_y)
Nc = range(1, 20)
kmeans = [KMeans(n_clusters=i) for i in Nc]
score = [kmeans[i].fit(X).score(X) for i in range(len(kmeans))]
plt.figure(figsize=(15,15))
plt.plot(Nc,score)
plt.xlabel('Number of Clusters')
plt.ylabel('Score')
plt.title('Elbow Curve')
plt.show()
return df, X, y
def etiquetado(k_cluster, X):
# k Max es el largo de este arreglo
colores=['red','green','blue','cyan','yellow', 'black', 'brown', 'orange', 'pink', 'purple', 'beige']
kmeans = KMeans(n_clusters=k_cluster).fit(X)
colores = colores[:k_cluster]
# Clasificacion
labels = kmeans.predict(X)
C = kmeans.cluster_centers_ # Centroides
asignar = []
for row in labels:
asignar.append(colores[row])
# Grafico de todos los puntos clasificados:
if X.shape[1] > 2:
fig = plt.figure(figsize=(20,20))
ax = Axes3D(fig)
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=asignar,s=60)
ax.scatter(C[:, 0], C[:, 1], C[:, 2], marker='*', c=colores, s=1000)
return labels, asignar, X, C, colores
def proyeccion_2d(df, col1, col2, asignar, C, colores, fig_size=(20, 20)):
f1 = df[col1].values
f2 = df[col2].values
plt.figure(figsize=fig_size)
plt.scatter(f1, f2, c=asignar, s=70)
plt.scatter(C[:, 0], C[:, 1], marker='*', c=colores, s=1000)
plt.xlabel(col1)
plt.ylabel(col2)
plt.show()
def generar_csv_final(ids_series, labels, colores):
final = pd.DataFrame()
# final['id'] = df_aux['id'].values
final['id'] = ids_series.values
final['label'] = labels;
cantidadGrupo = pd.DataFrame()
cantidadGrupo['color'] = colores
cantidadGrupo['cantidad'] = final.groupby('label').size()
display(cantidadGrupo)
return final
columnas_basicas = ['metroscubiertos', 'metrostotales', 'antiguedad', 'habitaciones', 'garages', 'banos',
'lat', 'lng', 'escuelascercanas', 'centroscomercialescercanos']
df_precio = df_aux_train['precio']
df_train, X, Y = generar_grafico(df_aux_train, columnas_basicas, df_precio)
labels, asignar, X, C, colores = etiquetado(6, X)
proyeccion_2d(df_train, 'metroscubiertos', 'metrostotales', asignar, C, colores)
proyeccion_2d(df_train, 'antiguedad', 'metrostotales', asignar, C, colores)
ids_series = df_aux_train['id']
final_train_columnas_basicas = generar_csv_final(ids_series, labels, colores)
final_train_columnas_basicas = final_train_columnas_basicas.rename(columns={'label':'kmeans_basicos'})
df_test, X, Y = generar_grafico(df_aux_test, columnas_basicas)
labels, asignar, X, C, colores = etiquetado(6, X)
proyeccion_2d(df_test, 'metroscubiertos', 'metrostotales', asignar, C, colores)
proyeccion_2d(df_test, 'antiguedad', 'metrostotales', asignar, C, colores)
ids_series = df_aux_test['id']
final_test_columnas_basicas = generar_csv_final(ids_series, labels, colores)
final_test_columnas_basicas = final_test_columnas_basicas.rename(columns={'label':'kmeans_basicos'})
columnas_superficie = ['metroscubiertos', 'metrostotales']
df_precio = df_aux_train['precio']
df_train, X, Y = generar_grafico(df_aux_train, columnas_superficie, df_precio)
labels, asignar, X, C, colores = etiquetado(8, X)
proyeccion_2d(df_train, 'metroscubiertos', 'metrostotales', asignar, C, colores)
ids_series = df_aux_train['id']
final_train_columnas_superficie = generar_csv_final(ids_series, labels, colores)
final_train_columnas_superficie = final_train_columnas_superficie.rename(columns={'label':'kmeans_superficie'})
df_test, X, Y = generar_grafico(df_aux_test, columnas_superficie)
labels, asignar, X, C, colores = etiquetado(8, X)
proyeccion_2d(df_test, 'metroscubiertos', 'metrostotales', asignar, C, colores)
ids_series = df_aux_test['id']
final_test_columnas_superficie = generar_csv_final(ids_series, labels, colores)
final_test_columnas_superficie = final_test_columnas_superficie.rename(columns={'label':'kmeans_superficie'})
def metros_totales_cubiertos(df):
punto20 = df_train['metrostotales'].quantile(0.2)
punto40 = df_train['metrostotales'].quantile(0.4)
punto60 = df_train['metrostotales'].quantile(0.6)
punto80 = df_train['metrostotales'].quantile(0.8)
punto20_cubiertos = df_train['metroscubiertos'].quantile(0.2)
punto40_cubiertos = df_train['metroscubiertos'].quantile(0.4)
punto60_cubiertos = df_train['metroscubiertos'].quantile(0.6)
punto80_cubiertos = df_train['metroscubiertos'].quantile(0.8)
df['metrostotales'] = df['metrostotales'].fillna(df['metroscubiertos'])
df['metroscubiertos'] = df['metroscubiertos'].fillna(df['metrostotales'])
df['metrostotales_log'] = np.log(df['metrostotales'])
df['metroscubiertos_log'] = np.log(df['metroscubiertos'])
df['porcentaje_metros'] = df['metroscubiertos']/df['metrostotales']
df['diferencia_metros'] = df['metrostotales'] - df['metroscubiertos']
df['intervalo_metros_totales'] = features.map_values(df['metrostotales'].values, lambda x: 1 if x<punto20 else (2 if punto20<x<punto40 else (3 if punto40<x<punto60 else(4 if punto60<x<punto80 else 5))))
df['intervalo_metros_cubiertos'] = features.map_values(df['metroscubiertos'].values, lambda x: 1 if x<punto20_cubiertos else (2 if punto20_cubiertos<x<punto40_cubiertos else (3 if punto40_cubiertos<x<punto60_cubiertos else(4 if punto60_cubiertos<x<punto80_cubiertos else 5))))
df['metroscubiertos_bins_unif'] = features.generar_intervalos_unif(df, 10, 'metroscubiertos')
df['metroscubiertos_bins_perc'] = features.generar_intervalos_perc(df, 10, 'metroscubiertos')
df['metroscubiertos_bins_unif'] = df['metroscubiertos_bins_unif'].astype(int)
df['metroscubiertos_bins_perc'] = df['metroscubiertos_bins_perc'].astype(int)
return df
df = df_aux_train.copy()
df = metros_totales_cubiertos(df)
columnas_metros_totales_cubiertos = ['metrostotales', 'metroscubiertos', 'metrostotales_log',
'metroscubiertos_log', 'porcentaje_metros', 'diferencia_metros', 'intervalo_metros_totales',
'intervalo_metros_cubiertos', 'metroscubiertos_bins_unif', 'metroscubiertos_bins_perc' ]
df_precio = df['precio']
df_train, X, Y = generar_grafico(df, columnas_metros_totales_cubiertos, df_precio)
labels, asignar, X, C, colores = etiquetado(6, X)
proyeccion_2d(df_train, 'intervalo_metros_cubiertos', 'diferencia_metros', asignar, C, colores)
ids_series = df['id']
final_train_columnas_metros_cubiertos = generar_csv_final(ids_series, labels, colores)
final_train_columnas_metros_cubiertos = final_train_columnas_metros_cubiertos.rename(columns={'label':'kmeans_metroscubiertos'})
df = df_aux_test.copy()
df = metros_totales_cubiertos(df)
columnas_metros_totales_cubiertos = ['metrostotales', 'metroscubiertos', 'metrostotales_log',
'metroscubiertos_log', 'porcentaje_metros', 'diferencia_metros', 'intervalo_metros_totales',
'intervalo_metros_cubiertos', 'metroscubiertos_bins_unif', 'metroscubiertos_bins_perc' ]
df_test, X, Y = generar_grafico(df, columnas_metros_totales_cubiertos)
labels, asignar, X, C, colores = etiquetado(6, X)
proyeccion_2d(df_test, 'intervalo_metros_cubiertos', 'diferencia_metros', asignar, C, colores)
ids_series = df['id']
final_test_columnas_metros_cubiertos = generar_csv_final(ids_series, labels, colores)
final_test_columnas_metros_cubiertos = final_test_columnas_metros_cubiertos.rename(columns={'label':'kmeans_metroscubiertos'})
def generar_features_fecha(df):
df['fecha'] = pd.to_datetime(df['fecha'])
df['anio'] = df['fecha'].dt.year
df['mes'] = df['fecha'].dt.month
df['dia'] = df['fecha'].dt.day
df['trimestre'] = (df['fecha'].dt.month)%3+1
df['delta_desde_datos'] = (df['fecha'] - df['fecha'].min())
df['dias_desde_datos'] = df['delta_desde_datos'].dt.days
df['meses_desde_datos'] = df['dias_desde_datos'] // 30 # Mas o menos...
df.pop('delta_desde_datos')
df['fecha'] = df['fecha'].astype(int)
return df
df = df_aux_train.copy()
df = generar_features_fecha(df)
columnas_por_fecha = ['fecha', 'anio', 'mes', 'dia', 'trimestre', 'dias_desde_datos', 'meses_desde_datos' ]
df_precio = df['precio']
df_train, X, Y = generar_grafico(df, columnas_por_fecha, df_precio)
labels, asignar, X, C, colores = etiquetado(11, X)
proyeccion_2d(df_train, 'dias_desde_datos', 'meses_desde_datos', asignar, C, colores)
ids_series = df['id']
final_train_columnas_fechas = generar_csv_final(ids_series, labels, colores)
final_train_columnas_fechas = final_train_columnas_fechas.rename(columns={'label':'kmeans_fechas'})
df = df_aux_test.copy()
df = generar_features_fecha(df)
df_test, X, Y = generar_grafico(df, columnas_por_fecha)
labels, asignar, X, C, colores = etiquetado(11, X)
proyeccion_2d(df_test, 'dias_desde_datos', 'meses_desde_datos', asignar, C, colores)
ids_series = df['id']
final_test_columnas_fechas = generar_csv_final(ids_series, labels, colores)
final_test_columnas_fechas = final_test_columnas_fechas.rename(columns={'label':'kmeans_fechas'})
columnas_lat_lng = ['lat', 'lng']
df_precio = df_aux_train['precio']
df_train, X, Y = generar_grafico(df_aux_train, columnas_lat_lng, df_precio)
labels, asignar, X, C, colores = etiquetado(8, X)
proyeccion_2d(df_train, 'lat', 'lng', asignar, C, colores)
ids_series = df_aux_train['id']
final_train_columnas_latlng = generar_csv_final(ids_series, labels, colores)
final_train_columnas_latlng = final_train_columnas_latlng.rename(columns={'label':'kmeans_latlng'})
df_test, X, Y = generar_grafico(df_aux_test, columnas_lat_lng)
labels, asignar, X, C, colores = etiquetado(8, X)
proyeccion_2d(df_test, 'lat', 'lng', asignar, C, colores)
ids_series = df_aux_test['id']
final_test_columnas_latlng = generar_csv_final(ids_series, labels, colores)
final_test_columnas_latlng = final_test_columnas_latlng.rename(columns={'label':'kmeans_latlng'})
clustering_train = pd.merge(final_train_columnas_basicas, final_train_columnas_superficie, on='id')
clustering_train = pd.merge(clustering_train, final_train_columnas_metros_cubiertos, on='id')
clustering_train = pd.merge(clustering_train, final_train_columnas_fechas, on='id')
clustering_train = pd.merge(clustering_train, final_train_columnas_latlng, on='id')
clustering_train.to_csv('./data/clustering_train_muchos.csv', index=False)
clustering_train
clustering_test = pd.merge(final_test_columnas_basicas, final_test_columnas_superficie, on='id')
clustering_test = pd.merge(clustering_test, final_test_columnas_metros_cubiertos, on='id')
clustering_test = pd.merge(clustering_test, final_test_columnas_fechas, on='id')
clustering_test = pd.merge(clustering_test, final_test_columnas_latlng, on='id')
clustering_test.to_csv('./data/clustering_test_muchos.csv', index=False)
clustering_test